package com.sharemedia.managers
{
	import com.sharemedia.consts.AppConst;
	import com.sharemedia.vos.Track;
	import com.sharemedia.vos.TrackInfo;
	import com.sharemedia.vos.TrackPacket;
	
	import flash.utils.ByteArray;
	
	import mx.utils.ObjectUtil;
	
	public class TrackBuffer
	{
		private var tracks:Vector.<Track> = new Vector.<Track>();
		
		private var buffer:Vector.<TrackPacket> = new Vector.<TrackPacket>();
		
		private var _currentTrack:Track;
		
		public function get currentTrack():Track
		{
			return _currentTrack;
		}
		
		
		public function TrackBuffer()
		{
		}
		
		public function addPacket(packet:TrackPacket):Boolean
		{
			var track:Track = findTrack(packet);
			if(packet.info)
			{
				if(!track.info || track.info.name != packet.info.name || packet.info.artist !=  packet.info.artist)
					track.info = new TrackInfo(packet.info.name, packet.info.artist);
				
				if(track.rating != packet.info.rating)
					track.rating = packet.info.rating;
				
				if(track.length != packet.info.length)
					track.length = packet.info.length;
			}
			buffer.push(packet);
			buffer.sort(sortFunc);
			
			// synchronize
			if(currentTrack != track && currentIndex < buffer.length - AppConst.BUFFER_SIZE)
			{
				currentIndex = buffer.length - AppConst.BUFFER_SIZE;
			}
			
			return buffer.length >= AppConst.BUFFER_SIZE;
		}
		public var bufferSize:Number = AppConst.BUFFER_SIZE*2
		private var currentIndex:Number = 0;
		public function extractPacket():TrackPacket
		{
			var packet:TrackPacket;
			if(currentIndex < buffer.length)
			{
				packet = buffer[currentIndex]; 
				
				var deleteCount:Number = Math.min(buffer.length-bufferSize, currentIndex);
				
				if(deleteCount > 0)
				{
					buffer.splice(0, deleteCount);
					currentIndex -= deleteCount-1;
				}
				else
				{
					currentIndex ++;
				}
				
				if(!currentTrack || packet.broadcastUid != currentTrack.broadcastUid)
				{
					_currentTrack = findTrackByBroadcatsUID(packet.broadcastUid);
				}
			}
			return packet;
		}
		
		public function getPlayedTracks():Array
		{
			var result:Array = new Array();
			
			for (var i:int = tracks.length-2; i >= 0; i--) 
			{
				if(tracks[i].info)
					result.push(tracks[i]);
			}
			return result;
		}
		
		private function findTrack(packet:TrackPacket):Track
		{
			var track:Track = findTrackByBroadcatsUID(packet.broadcastUid);
			
			if(!track)
			{
				track = new Track(packet.trackUid);
				track.broadcastUid = packet.broadcastUid;
				tracks.push(track);
			}
			
			return track;
		}
		
		private function findTrackByBroadcatsUID(uid:String):Track
		{
			for each (var track:Track in tracks) 
			{
				if(track.broadcastUid == uid)
					return track;
			}
			
			return null;
		}
		
		private function sortFunc(a:TrackPacket, b:TrackPacket):Number
		{
			return ObjectUtil.numericCompare(a.sendTime, b.sendTime);
		}
	}
}